using Microsoft.Extensions.Logging;
using SumerCoreDevOps.ExecuteNodeApi.Services;
using SumerCoreDevOps.Infrastructure.Libraries;
using SumerCoreDevOps.Infrastructure.Security;
using SumerCoreDevOps.Shared.Models.Messages;
using System.Text.Json;

namespace SumerCoreDevOps.ExecuteNodeApi.Handlers;

/// <summary>
/// Docker 部署处理器
/// </summary>
public class DeployDockerHandler : IStepHandler
{
    private readonly ILogger<DeployDockerHandler> _logger;
    private readonly DockerLibrary _dockerLibrary;
    private readonly TaskExecutor _taskExecutor;

    public DeployDockerHandler(
        ILogger<DeployDockerHandler> logger,
        DockerLibrary dockerLibrary,
        TaskExecutor taskExecutor)
    {
        _logger = logger;
        _dockerLibrary = dockerLibrary;
        _taskExecutor = taskExecutor;
    }

    public async Task<StepExecutionResult> ExecuteAsync(WorkflowStepDispatchMessage message)
    {
        try
        {
            var config = JsonSerializer.Deserialize<DockerDeployConfig>(message.StepConfig);

            if (config == null)
            {
                return new StepExecutionResult
                {
                    Success = false,
                    ErrorMessage = "Docker 部署配置无效"
                };
            }

            // 订阅 Docker 日志事件，转发到控制面板
            _dockerLibrary.OnLog += async (logMessage, logLevel) =>
            {
                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, logMessage, logLevel);
            };

            // 1. 构建镜像
            if (!string.IsNullOrEmpty(config.DockerfilePath))
            {
                var buildSuccess = await _dockerLibrary.BuildImageAsync(
                    config.DockerfilePath,
                    config.ImageName!,
                    config.Tag ?? "latest");

                if (!buildSuccess)
                {
                    return new StepExecutionResult
                    {
                        Success = false,
                        ErrorMessage = "Docker 镜像构建失败"
                    };
                }
            }

            // 2. 推送镜像（如果配置了）
            if (!string.IsNullOrEmpty(config.Registry))
            {
                // 获取 Docker 凭证
                string? username = null;
                string? password = null;

                if (message.EncryptedCredentials.TryGetValue(Shared.Enums.CredentialType.Docker, out var encryptedCred))
                {
                    try
                    {
                        // 解密凭证
                        var decryptedJson = EncryptionHelper.Decrypt(encryptedCred);
                        var dockerCredential = JsonSerializer.Deserialize<DockerCredential>(decryptedJson);

                        if (dockerCredential != null)
                        {
                            username = dockerCredential.Username;
                            password = dockerCredential.Password;
                            _logger.LogInformation("Docker 凭证解密成功，Registry: {Registry}, Username: {Username}",
                                dockerCredential.Registry, username);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning(ex, "Docker 凭证解密失败，将尝试匿名推送");
                    }
                }

                var pushSuccess = await _dockerLibrary.PushImageAsync(
                    $"{config.Registry}/{config.ImageName}",
                    config.Tag ?? "latest",
                    username,
                    password);

                if (!pushSuccess)
                {
                    return new StepExecutionResult
                    {
                        Success = false,
                        ErrorMessage = "Docker 镜像推送失败"
                    };
                }
            }

            return new StepExecutionResult
            {
                Success = true,
                Progress = 100,
                OutputContext = new Dictionary<string, string>
                {
                    ["DOCKER_IMAGE"] = $"{config.ImageName}:{config.Tag ?? "latest"}",
                    ["DOCKER_REGISTRY"] = config.Registry ?? "local"
                }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Docker 部署处理器执行失败");
            return new StepExecutionResult
            {
                Success = false,
                ErrorMessage = ex.Message
            };
        }
    }
}

public class DockerDeployConfig
{
    public string? ImageName { get; set; }
    public string? Tag { get; set; }
    public string? DockerfilePath { get; set; }
    public string? Registry { get; set; }
}
